package fr.obsmip.sedoo.client.activity;

import java.util.ArrayList;
import java.util.List;

import javax.swing.text.View;

import com.google.api.gwt.oauth2.client.Auth;
import com.google.api.gwt.oauth2.client.AuthRequest;
import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;

import fr.obsmip.sedoo.client.ClientFactory;
import fr.obsmip.sedoo.client.Logger;
import fr.obsmip.sedoo.client.PortailRBV;
import fr.obsmip.sedoo.client.ShortcutFactory;
import fr.obsmip.sedoo.client.event.ActionEventConstant;
import fr.obsmip.sedoo.client.event.UserLoginEvent;
import fr.obsmip.sedoo.client.message.Message;
import fr.obsmip.sedoo.client.place.WelcomePlace;
import fr.obsmip.sedoo.client.service.GoogleService;
import fr.obsmip.sedoo.client.service.GoogleServiceAsync;
import fr.obsmip.sedoo.client.service.UserService;
import fr.obsmip.sedoo.client.service.UserServiceAsync;
import fr.obsmip.sedoo.client.ui.LoginView;
import fr.obsmip.sedoo.client.ui.misc.Shortcut;
import fr.obsmip.sedoo.shared.constant.LogConstant;
import fr.obsmip.sedoo.shared.domain.RBVUserDTO;
import fr.sedoo.commons.client.event.ActionStartEvent;
import fr.sedoo.commons.client.message.CommonMessages;
import fr.sedoo.commons.client.mvp.place.LoginPlace;
import fr.sedoo.commons.client.widget.DialogBoxTools;

public class LoginActivity extends RBVAbstractActivity implements LoginView.Presenter {
	private LoginView loginView;

	private static final UserServiceAsync USER_SERVICE = GWT.create(UserService.class);
	private static final GoogleServiceAsync GOOGLE_SERVICE = GWT.create(GoogleService.class);
	private static final Auth AUTH = Auth.get();

	private static final String GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/auth";
	private static final String GOOGLE_CLIENT_ID = "1054144370632.apps.googleusercontent.com";
	private static final String GOOGLE_EMAIL_SCOPE = "https://www.googleapis.com/auth/userinfo.email";
	private static final String GOOGLE_PROFILE_SCOPE = "https://www.googleapis.com/auth/userinfo.profile";

	private static final String FACEBOOK_AUTH_URL = "https://www.facebook.com/dialog/oauth";
	private static final String FACEBOOK_CLIENT_ID = "165564693624550";
	private static final String FACEBOOK_EMAIL_SCOPE = "email";
	private static final String FACEBOOK_PROFIL_SCOPE = "user";
	private static final String FACEBOOK_SCOPE_DELIMITER = ",";

	private static final String LINKED_IN_AUTH_URL = "https://www.linkedin.com/uas/oauth2/authorization";
	private static final String LINKED_IN_CLIENT_ID = "d01htlxn47xu";
	private static final String LINKED_IN_EMAIL_SCOPE = "r_fullprofile";
	private static final String LINKED_IN_PROFILE_SCOPE = "r_emailaddress";


	private Place destinationPlace;

	public LoginActivity(LoginPlace place, ClientFactory clientFactory) {
		super(clientFactory);
		if (place.getWishedPlace() != null)
		{
			destinationPlace = place.getWishedPlace();
		}
		else
		{
			destinationPlace = new WelcomePlace();
		}
	}

	@Override
	public void start(AcceptsOneWidget containerWidget, EventBus eventBus) {
		loginView = clientFactory.getLoginView();

		if (destinationPlace instanceof WelcomePlace)
		{
			loginView.setLoginFirstMessageVisible(false);
		}
		else
		{
			loginView.setLoginFirstMessageVisible(true);
		}

		loginView.setPresenter(this);
		containerWidget.setWidget(loginView.asWidget());
		broadcastActivityTitle(Message.INSTANCE.loginViewHeader());
		List<Shortcut> shortcuts = new ArrayList<Shortcut>();
		shortcuts.add(ShortcutFactory.getWelcomeShortcut());
		shortcuts.add(ShortcutFactory.getLoginShortcut());
		clientFactory.getBreadCrumb().refresh(shortcuts);


		/*
		 * If the user comes back to the login form after a logout a reset is necessary
		 */
		if (PortailRBV.getClientFactory().getUserManager().getUser() == null)
		{
			loginView.reset();
		}
	}

	@Override
	public void login(String login, String password) 
	{
		final ActionStartEvent e = new ActionStartEvent(CommonMessages.INSTANCE.connecting(), ActionEventConstant.USER_LOGIN_EVENT, true);
		clientFactory.getEventBus().fireEvent(e);
		USER_SERVICE.login(login, password, new AsyncCallback<RBVUserDTO>() {

			@Override
			public void onSuccess(RBVUserDTO user) {

				clientFactory.getEventBus().fireEvent(e.getEndingEvent());
				broadcastLogin(user);
			}

			@Override
			public void onFailure(Throwable caught) 
			{
				DialogBoxTools.modalAlert(CommonMessages.INSTANCE.error(), Message.INSTANCE.loginViewConnectFailureMessage());
				clientFactory.getEventBus().fireEvent(e.getEndingEvent());
				loginView.activateLoginButtons();

			}
		});

	}

	@Override
	public void loginWithLinkedIn() {
		
	}

	@Override
	public void loginWithGoogle() {
		final ActionStartEvent e = new ActionStartEvent(CommonMessages.INSTANCE.connecting(), ActionEventConstant.USER_LOGIN_EVENT, true);
		clientFactory.getEventBus().fireEvent(e);
		final AuthRequest req = new AuthRequest(GOOGLE_AUTH_URL, GOOGLE_CLIENT_ID).withScopes(GOOGLE_EMAIL_SCOPE, GOOGLE_PROFILE_SCOPE);

		AUTH.login(req, new Callback<String, Throwable>() {
			@Override
			public void onSuccess(String token) {


				GOOGLE_SERVICE.getUserFromToken(token, new AsyncCallback<RBVUserDTO>() {

					@Override
					public void onSuccess(RBVUserDTO user) {
						broadcastLogin(user);
						clientFactory.getEventBus().fireEvent(e.getEndingEvent());
					}

					@Override
					public void onFailure(Throwable caught) {
						DialogBoxTools.modalAlert(CommonMessages.INSTANCE.error(), Message.INSTANCE.loginViewConnectFailureMessage());
						clientFactory.getEventBus().fireEvent(e.getEndingEvent());
						loginView.activateLoginButtons();
					}
				});
			}

			@Override
			public void onFailure(Throwable caught) {
				DialogBoxTools.modalAlert(CommonMessages.INSTANCE.error(), Message.INSTANCE.loginViewConnectFailureMessage());
				clientFactory.getEventBus().fireEvent(e.getEndingEvent());
				loginView.activateLoginButtons();
			}
		});		
	}

	@Override
	public void loginWithFacebook() {
		final AuthRequest req = new AuthRequest(FACEBOOK_AUTH_URL, FACEBOOK_CLIENT_ID).withScopes(FACEBOOK_EMAIL_SCOPE).withScopeDelimiter(FACEBOOK_SCOPE_DELIMITER);

		AUTH.login(req, new Callback<String, Throwable>() {
			@Override
			public void onSuccess(String token) {


				GOOGLE_SERVICE.getUserFromToken(token, new AsyncCallback<RBVUserDTO>() {

					@Override
					public void onSuccess(RBVUserDTO user) {
						broadcastLogin(user);
					}

					@Override
					public void onFailure(Throwable caught) {
						DialogBoxTools.modalAlert(CommonMessages.INSTANCE.error(), Message.INSTANCE.loginViewConnectFailureMessage());
						loginView.activateLoginButtons();

					}
				});
			}

			@Override
			public void onFailure(Throwable caught) {
				DialogBoxTools.modalAlert(CommonMessages.INSTANCE.error(), Message.INSTANCE.loginViewConnectFailureMessage());
				loginView.activateLoginButtons();
			}
		});		
	}


	private void broadcastLogin(RBVUserDTO user) 
	{
		PortailRBV.getClientFactory().getUserManager().setUser(user);
		loginView.updateSucces();
		clientFactory.getEventBus().fireEvent(new UserLoginEvent(user));
		Logger.addLog(user, LogConstant.SESSION_CATEGORY, LogConstant.CONNEXION_ACTION, "User "+user.getName()+" has logged in.");
		Timer t = new Timer() {
			public void run() {
				PortailRBV.getPresenter().goTo(destinationPlace);
			}
		};

		t.schedule(500);
	}


}
